#include <iostream>
#include <typeinfo>
#include <cassert>
#include <string>
#include <unistd.h>
class Any
{
private:
    class holder
    {

    public:
        virtual ~holder() {}
        virtual const std::type_info &type() = 0;
        // 深拷贝支持：多态克隆确保复制完整对象
        virtual holder *clone() = 0;
    };
    template <class T>
    class placeholder : public holder
    {
    public:
        placeholder(const T &val) : _val(val) {}
        // 获取子类对象保存的数据类型
        const std::type_info &type() override
        {
            return typeid(T);
        }

        // 针对当前的对象自身，克隆出一个新的子类对象
        holder *clone() override
        {
            return new placeholder(_val);
        }

    public:
        T _val;
    };
    // 指向不同类型数据的通用接口
    holder *_content; // 在new一个子类对象的时候指定类型，让父类指向这个子类

public:
    // 无参构造
    Any() : _content(nullptr)
    {
    }
    template <class T>
    // 通用构造
    Any(const T &val) : _content(new placeholder<T>(val))
    {
    }
    // 拷贝构造
    Any(const Any &other) : _content(other._content ? other._content->clone() : nullptr)
    {
    }
    ~Any()
    {
        delete _content;
    }
    //&为了进行一个连续的交换
    Any &swap(Any &other)
    {
        std::swap(_content, other._content);
        return *this;
    }

    // 返回在子类对象中保存的数据的指针
    template <class T>
    T *get()
    {
        if (!_content)
            return nullptr;
        // 想要获取的数据类型必须和保存的数据类型一致
        assert(typeid(T) == _content->type());
        // 向下转型获取存储的值
        return &static_cast<placeholder<T> *>(_content)->_val;
    }
    // 赋值运算符的重载函数
    template <class T>
    Any &operator=(const T &val)
    {
        // 为val构造一个临时的通用容器，然后与当前容器自身进行指针交换，临时对象释放的时候，原先保存的数据也就被释放
        Any(val).swap(*this); // 创建临时对象并交换
        return *this;
    }

    Any &operator=(const Any &other)
    {
        Any(other).swap(*this); // 拷贝构造临时对象并交换

        return *this;
    }
};

class Test
{
public:
    Test()
    {
        std::cout << "构造" << std::endl;
    }
    Test(const Test &t)
    {
        std::cout << "拷贝构造" << std::endl;
    }
    ~Test()
    {
        std::cout << "析构" << std::endl;
    }
};

int main()
{
    Any a;
    {
        Test t;
        a = t;
    }

    a = 10;
    int *pa = a.get<int>();
    std::cout << *pa << std::endl;
    a = std::string("nihao");
    std::string *ps = a.get<std::string>();
    std::cout << *ps << std::endl;
}

// int main()
// {
//     Any a;

//     {

//         Test t;
//         a = t;
//     }

//     while (1)
//     {
//         sleep(1);
//     }
//     return 0;
// }